#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

#include "log.h"

char gCommonFilePath[128] = "./commom.log";
char gErrorFilePath[128] = "./error.log";
char gFatalFilePath[128] = "./fatal.log";
#define SUCCESS 0
#define FAIL -1
#define CONTENT_BUFF 2048

using namespace std;

CLogSystem::CLogSystem()
{
	mOutputMode = CONSOLE;
	mOutputLevel = INFO_LEVEL;
};

CLogSystem::~CLogSystem(){};


void CLogSystem::INFO(char* content)
{
	if(content == NULL || mOutputLevel < INFO_LEVEL) return;

	char newcontent[CONTENT_BUFF]={0};
	sprintf(newcontent,"[INFO] %s %s",GetDateString(),content);
	if(mOutputMode == CONSOLE)
		printf("%s",newcontent);
	else
		Record2File(gCommonFilePath,content);
};

void CLogSystem::DEBUG(char* content)
{
	if(content == NULL || mOutputLevel < DEBUG_LEVEL) return;

	char newcontent[CONTENT_BUFF]={0};
	sprintf(newcontent,"[DEBUG] %s %s",GetDateString(),content);
	if(mOutputMode == CONSOLE)
		printf("%s",newcontent);
	else
		Record2File(gCommonFilePath,content);
};

void CLogSystem::WARNING(char* content)
{
	if(content == NULL || mOutputLevel < WARNING_LEVEL) return;

	char newcontent[CONTENT_BUFF]={0};
	sprintf(newcontent,"[WARNING] %s %s",GetDateString(),content);
	if(mOutputMode == CONSOLE)
		printf("%s",newcontent);
	else
		Record2File(gCommonFilePath,content);
};

void CLogSystem::ERROR(char* content)
{
	if(content == NULL || mOutputLevel < ERROR_LEVEL) return;

	char newcontent[CONTENT_BUFF]={0};
	sprintf(newcontent,"[ERROR] %s %s",GetDateString(),content);
	if(mOutputMode == CONSOLE)
		printf("%s",newcontent);
	Record2File(gErrorFilePath,newcontent);
};

void CLogSystem::FATAL(char* content)
{
	if(content == NULL || mOutputLevel < FATAL_LEVEL) return;

	char newcontent[CONTENT_BUFF]={0};
	sprintf(newcontent,"[FATAL] %s %s",GetDateString(),content);
	if(mOutputMode == CONSOLE)
		printf("%s",newcontent);
	Record2File(gFatalFilePath,newcontent);
};

int CLogSystem::SetOutputMode(OUTPUTMODE mode)
{
	return mOutputMode = mode;
};

int CLogSystem::SetOutputLevel(OUTPUTLEVEL level)
{
	return mOutputLevel = level;
};

char* CLogSystem::GetDateString(void)
{
	struct tm t;
	struct timespec ts;
    char date_time[64] = {0};
    char* strtime = new char[64];
    strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localtime_r(&ts.tv_sec, &t));
    sprintf(strtime, "%s.%ld", date_time, ts.tv_nsec);
	return strtime;
};

int CLogSystem::Record2File(const char* path, char* content)
{
	FILE *mlogDataFile = fopen(path, "a+");
	if(NULL != mlogDataFile)
	{
		fwrite(content, strlen(content), 1, mlogDataFile);
		fclose(mlogDataFile);
		return SUCCESS;
	}
	printf("open file failed\n");
	return FAIL;
};

